Running A Screensaver - Two Cases

Last Updated: 2nd May

CASE ONE:

For this case we will assume that you (or your user) have installed the screensaver. Go to Installing A Screensaver - Two Methods if you need to know how that is done programmatically. Running an installed screensaver is very simple. It involves sending a Win32 system command, or in other words the message WM_SYSCOMMAND. Specifically, you need to send this message with the wParam parameter set to SC_SCREENSAVE (funnily enough). Sending this message will execute the screen saver application specified in the [boot] section of the SYSTEM.INI file, according to the Win32 docs. And it does. So, you should use the SendMessage API the following way:

SendMessage(Application.Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
That was easy enough!

CASE TWO:

Sometimes, though, for whatever reason, you will want to run screensavers which are not necessarily installed, nor residing in the Windows or System directory. What then? Well, let's examine this case. Recall that screensavers are just executables which have been renamed. Great, you say! I can use ExecuteFile as in the following:

ExecuteFile('Screensaver Composer.scr', '/s', 'C:\Windows\', SW_SHOW);
Sorry, but this is just not reliable. The reason I'll relate to you through a story. Once upon a time, I downloaded what appeared to a nifty screensaver program. You could add your own pictures to it, as well as sound and video. Unfortunately, this program decided to associate the *.scr extension to its own configuration program. Now that is a big no-no! Why? Well, when I uninstalled this program, it didn't restore the old Win95 association. No longer could I configure or run a screensaver via its context menu. If I double-clicked the screensaver file in Explorer it would search for the program I had just uninstalled! And that is what the ExecuteFile command would do in this case. Now I'm pretty sure I'm not the only victim of this vandal program, so we need a more reliable way of running a screensaver. That reliable way is through the CreateProcess API function. While ExecuteFile (which wraps up the ShellExecute API) searches for the associated executable, CreateProcess runs it under the assumption that it's an executable. It couldn't care less about the file extension (except to identify the file!). CreateProcess is a little tricky to use, so I've written a little procedure which encapsulates it:

procedure RunSaver(SaverPath, SaverName, SaverParam : String);
var
  zAppName : String;
  StartupInfo : TStartupInfo;
  ProcessInfo : TProcessInformation;
begin
  if Copy(SaverPath, Length(SaverPath), 1) <> '\' then
    SaverPath := SaverPath + '\';
  zAppName := SaverPath + SaverName + '' + SaverParam;
  FillChar(StartupInfo,SizeOf(TStartupInfo),#0);
  FillChar(ProcessInfo,SizeOf(TProcessInformation),#0);
  StartupInfo.cb := Sizeof(StartupInfo);
  CreateProcess(nil,                        {^executable name}
                PChar(zAppName),            {^command line string}
                nil,                        {^process security attributes}
                nil,                        {^thread security attributes}
                false,                      {handle inheritance flag}
                CREATE_NEW_PROCESS_GROUP or {creation flags}
                NORMAL_PRIORITY_CLASS,
                nil,                        {^new environment block}
                nil,                        {^current directory name}
                StartupInfo,                {STARTUPINFO}
                ProcessInfo);               {PROCESSINFO}
end;
SaverPath is the directory where the screensaver is located, SaverName is the name of the screensaver, and SaverParam is the command-line parameter you would like to pass ('/s' will run the screensaver and '/c' will bring up its configuration dialog). And you would use it like so:

RunSaver('C:\MyDir\', 'Red Balloons.scr', '/s');
This should run the screensaver regardless of where it's located and whether or not it's installed. By the way, for those of you who have had their *.scr file extension association corrupted by vandal programs, the way to fix it up is to run the Microsoft TweakUI application. Go to the Repair tab, and click on the Repair Associations button.
lonewolf@tig.com.au